if ( setup_guest(xc_handle, domid, memsize, image, image_size, &ctxt) < 0 )
{
- ERROR("Error constructing guest OS");
goto error_out;
}
if ( !IS_ELF(*ehdr) )
{
- ERROR("Kernel image does not have an ELF header.");
+ xc_set_error(XC_INVALID_KERNEL,
+ "Kernel image does not have an ELF header.");
return -EINVAL;
}
if ( (ehdr->e_phoff + (ehdr->e_phnum * ehdr->e_phentsize)) > elfsize )
{
- ERROR("ELF program headers extend beyond end of image.");
+ xc_set_error(XC_INVALID_KERNEL,
+ "ELF program headers extend beyond end of image.");
return -EINVAL;
}
if ( (ehdr->e_shoff + (ehdr->e_shnum * ehdr->e_shentsize)) > elfsize )
{
- ERROR("ELF section headers extend beyond end of image.");
+ xc_set_error(XC_INVALID_KERNEL,
+ "ELF section headers extend beyond end of image.");
return -EINVAL;
}
/* Find the section-header strings table. */
if ( ehdr->e_shstrndx == SHN_UNDEF )
{
- ERROR("ELF image has no section-header strings table (shstrtab).");
+ xc_set_error(XC_INVALID_KERNEL,
+ "ELF image has no section-header strings table (shstrtab).");
return -EINVAL;
}
shdr = (Elf32_Shdr *)(elfbase + ehdr->e_shoff +
(ehdr->e_entry < kernstart) ||
(ehdr->e_entry > kernend) )
{
- ERROR("Malformed ELF image.");
+ xc_set_error(XC_INVALID_KERNEL,
+ "Malformed ELF image.");
return -EINVAL;
}
if ( probe_elf(image, image_size, load_funcs) &&
probe_bin(image, image_size, load_funcs) )
{
- ERROR( "Unrecognized image format" );
+ xc_set_error(XC_INVALID_KERNEL, "Not a valid ELF or raw kernel image");
return -EINVAL;
}
xen_capabilities_info_t xen_caps = "";
if (xc_version(xc_handle, XENVER_capabilities, &xen_caps) != 0) {
- ERROR("Cannot determine host capabilities.");
+ xc_set_error(XC_INVALID_KERNEL,
+ "Cannot determine host capabilities.");
return 0;
}
if (strstr(xen_caps, "xen-3.0-x86_32p")) {
if (dsi->pae_kernel == PAEKERN_no) {
- ERROR("Non PAE-kernel on PAE host.");
+ xc_set_error(XC_INVALID_KERNEL,
+ "Non PAE-kernel on PAE host.");
return 0;
}
} else if (dsi->pae_kernel != PAEKERN_no) {
- ERROR("PAE-kernel on non-PAE host.");
+ xc_set_error(XC_INVALID_KERNEL,
+ "PAE-kernel on non-PAE host.");
return 0;
}
console_evtchn, console_mfn,
features_bitmap) < 0 )
{
- ERROR("Error constructing guest OS");
goto error_out;
}
*/
#if defined(__ia64__)
#define ELFCLASS ELFCLASS64
+#define ELFCLASS_DESC "64-bit"
+
#define ELFDATA ELFDATA2LSB
+#define ELFDATA_DESC "Little-Endian"
+
#define ELFMACHINE EM_IA_64
+#define ELFMACHINE_DESC "ia64"
+
+
#elif defined(__i386__)
#define ELFCLASS ELFCLASS32
+#define ELFCLASS_DESC "32-bit"
+
#define ELFDATA ELFDATA2LSB
+#define ELFDATA_DESC "Little-Endian"
+
#define ELFMACHINE EM_386
+#define ELFMACHINE_DESC "i386"
+
+
#elif defined(__x86_64__)
#define ELFCLASS ELFCLASS64
+#define ELFCLASS_DESC "64-bit"
+
#define ELFDATA ELFDATA2LSB
+#define ELFDATA_DESC "Little-Endian"
+
#define ELFMACHINE EM_X86_64
+#define ELFMACHINE_DESC "x86_64"
+
+
#elif defined(__powerpc__)
#define ELFCLASS ELFCLASS64
+#define ELFCLASS_DESC "64-bit"
+
#define ELFDATA ELFDATA2MSB
+#define ELFDATA_DESC "Big-Endian"
+
#define ELFMACHINE EM_PPC64
+#define ELFMACHINE_DESC "ppc64"
#endif
int probe_elf(const char *image,
*defined = 1;
return *(uint64_t*)ELFNOTE_DESC(note);
default:
- ERROR("elfnotes: unknown data size %#x for numeric type note %#x\n",
+ xc_set_error(XC_INVALID_KERNEL,
+ "elfnotes: unknown data size %#x for numeric type note %#x\n",
note->descsz, type);
return 0;
}
if ( !IS_ELF(*ehdr) )
{
- ERROR("Kernel image does not have an ELF header.");
+ xc_set_error(XC_INVALID_KERNEL,
+ "Kernel image does not have an ELF header.");
return -EINVAL;
}
- if ( (ehdr->e_ident[EI_CLASS] != ELFCLASS) ||
- (ehdr->e_machine != ELFMACHINE) ||
- (ehdr->e_ident[EI_DATA] != ELFDATA) ||
- (ehdr->e_type != ET_EXEC) )
+ if (ehdr->e_machine != ELFMACHINE)
+ {
+ xc_set_error(XC_INVALID_KERNEL,
+ "Kernel ELF architecture '%d' does not match Xen architecture '%d' (%s)",
+ ehdr->e_machine, ELFMACHINE, ELFMACHINE_DESC);
+ return -EINVAL;
+ }
+ if (ehdr->e_ident[EI_CLASS] != ELFCLASS)
+ {
+ xc_set_error(XC_INVALID_KERNEL,
+ "Kernel ELF wordsize '%d' does not match Xen wordsize '%d' (%s)",
+ ehdr->e_ident[EI_CLASS], ELFCLASS, ELFCLASS_DESC);
+ return -EINVAL;
+ }
+ if (ehdr->e_ident[EI_DATA] != ELFDATA)
+ {
+ xc_set_error(XC_INVALID_KERNEL,
+ "Kernel ELF endianness '%d' does not match Xen endianness '%d' (%s)",
+ ehdr->e_ident[EI_DATA], ELFDATA, ELFDATA_DESC);
+ return -EINVAL;
+ }
+ if (ehdr->e_type != ET_EXEC)
{
- ERROR("Kernel not a Xen-compatible Elf image.");
+ xc_set_error(XC_INVALID_KERNEL,
+ "Kernel ELF type '%d' does not match Xen type '%d'",
+ ehdr->e_type, ET_EXEC);
return -EINVAL;
}
if ( (ehdr->e_phoff + (ehdr->e_phnum*ehdr->e_phentsize)) > image_len )
{
- ERROR("ELF program headers extend beyond end of image.");
+ xc_set_error(XC_INVALID_KERNEL,
+ "ELF program headers extend beyond end of image.");
return -EINVAL;
}
if ( (ehdr->e_shoff + (ehdr->e_shnum*ehdr->e_shentsize)) > image_len )
{
- ERROR("ELF section headers extend beyond end of image.");
+ xc_set_error(XC_INVALID_KERNEL,
+ "ELF section headers extend beyond end of image.");
return -EINVAL;
}
/* Find the section-header strings table. */
if ( ehdr->e_shstrndx == SHN_UNDEF )
{
- ERROR("ELF image has no section-header strings table (shstrtab).");
+ xc_set_error(XC_INVALID_KERNEL,
+ "ELF image has no section-header strings table (shstrtab).");
return -EINVAL;
}
shdr = (Elf_Shdr *)(image + ehdr->e_shoff +
if ( ( loader == NULL || strncmp(loader, "generic", 7) ) &&
( guest_os == NULL || strncmp(guest_os, "linux", 5) ) )
{
- ERROR("Will only load images built for the generic loader "
- "or Linux images");
+ xc_set_error(XC_INVALID_KERNEL,
+ "Will only load images built for the generic loader "
+ "or Linux images");
return -EINVAL;
}
if ( xen_version == NULL || strncmp(xen_version, "xen-3.0", 7) )
{
- ERROR("Will only load images built for Xen v3.0");
+ xc_set_error(XC_INVALID_KERNEL,
+ "Will only load images built for Xen v3.0");
return -EINVAL;
}
}
else
{
#if defined(__x86_64__) || defined(__i386__)
- ERROR("Not a Xen-ELF image: "
- "No ELF notes or '__xen_guest' section found.");
+ xc_set_error(XC_INVALID_KERNEL,
+ "Not a Xen-ELF image: "
+ "No ELF notes or '__xen_guest' section found.");
return -EINVAL;
#endif
}
if ( elf_pa_off_defined && !virt_base_defined )
{
- ERROR("Neither ELF_PADDR_OFFSET nor VIRT_BASE found in ELF "
- " notes or __xen_guest section.");
+ xc_set_error(XC_INVALID_KERNEL,
+ "Neither ELF_PADDR_OFFSET nor VIRT_BASE found in ELF "
+ " notes or __xen_guest section.");
return -EINVAL;
}
vaddr = phdr->p_paddr - dsi->elf_paddr_offset + dsi->v_start;
if ( (vaddr + phdr->p_memsz) < vaddr )
{
- ERROR("ELF program header %d is too large.", h);
+ xc_set_error(XC_INVALID_KERNEL,
+ "ELF program header %d is too large.", h);
return -EINVAL;
}
(dsi->v_kernentry > kernend) ||
(dsi->v_start > kernstart) )
{
- ERROR("ELF start or entries are out of bounds.");
+ xc_set_error(XC_INVALID_KERNEL,
+ "ELF start or entries are out of bounds.");
return -EINVAL;
}
#include "xc_private.h"
#include "xg_private.h"
+#include <stdarg.h>
+
+static __thread xc_error last_error = { XC_ERROR_NONE, ""};
+#if DEBUG
+static xc_error_handler error_handler = xc_default_error_handler;
+#else
+static xc_error_handler error_handler = NULL;
+#endif
+
+void xc_default_error_handler(const xc_error const *err)
+{
+ const char *desc = xc_error_code_to_desc(err->code);
+ fprintf(stderr, "ERROR %s: %s\n", desc, err->message);
+}
+
+const xc_error const *xc_get_last_error(void)
+{
+ return &last_error;
+}
+
+void xc_clear_last_error(void)
+{
+ last_error.code = XC_ERROR_NONE;
+ last_error.message[0] = '\0';
+}
+
+const char *xc_error_code_to_desc(int code)
+{
+ /* Sync to members of xc_error_code enumeration in xenctrl.h */
+ switch ( code )
+ {
+ case XC_ERROR_NONE:
+ return "No error details";
+ case XC_INTERNAL_ERROR:
+ return "Internal error";
+ case XC_INVALID_KERNEL:
+ return "Invalid kernel";
+ }
+
+ return "Unknown error code";
+}
+
+xc_error_handler xc_set_error_handler(xc_error_handler handler)
+{
+ xc_error_handler old = error_handler;
+ error_handler = handler;
+ return old;
+}
+
+
+static void _xc_set_error(int code, const char *msg)
+{
+ last_error.code = code;
+ strncpy(last_error.message, msg, XC_MAX_ERROR_MSG_LEN - 1);
+ last_error.message[XC_MAX_ERROR_MSG_LEN-1] = '\0';
+}
+
+void xc_set_error(int code, const char *fmt, ...)
+{
+ int saved_errno = errno;
+ char msg[XC_MAX_ERROR_MSG_LEN];
+ va_list args;
+
+ va_start(args, fmt);
+ vsnprintf(msg, XC_MAX_ERROR_MSG_LEN-1, fmt, args);
+ msg[XC_MAX_ERROR_MSG_LEN-1] = '\0';
+ va_end(args);
+
+ _xc_set_error(code, msg);
+
+ errno = saved_errno;
+
+ if ( error_handler != NULL )
+ error_handler(&last_error);
+}
+
int lock_pages(void *addr, size_t len)
{
int e = 0;
#define PPRINTF(_f, _a...)
#endif
-#define ERROR(_m, _a...) \
-do { \
- int __saved_errno = errno; \
- DPRINTF("ERROR: " _m "\n" , ## _a ); \
- errno = __saved_errno; \
-} while (0)
+void xc_set_error(int code, const char *fmt, ...);
+
+#define ERROR(_m, _a...) xc_set_error(XC_INTERNAL_ERROR, _m , ## _a )
+#define PERROR(_m, _a...) xc_set_error(XC_INTERNAL_ERROR, _m " (%d = %s)", \
+ _m , ## _a , errno, strerror(errno))
int lock_pages(void *addr, size_t len);
void unlock_pages(void *addr, size_t len);
-#define PERROR(_m, _a...) \
-do { \
- int __saved_errno = errno; \
- DPRINTF("ERROR: " _m " (%d = %s)\n" , ## _a , \
- __saved_errno, strerror(__saved_errno)); \
- errno = __saved_errno; \
-} while (0)
-
static inline void safe_munlock(const void *addr, size_t len)
{
int saved_errno = errno;
int xc_hvm_set_pci_link_route(
int xc_handle, domid_t dom, uint8_t link, uint8_t isa_irq);
+
+typedef enum {
+ XC_ERROR_NONE = 0,
+ XC_INTERNAL_ERROR = 1,
+ XC_INVALID_KERNEL = 2,
+} xc_error_code;
+
+#define XC_MAX_ERROR_MSG_LEN 1024
+typedef struct {
+ int code;
+ char message[XC_MAX_ERROR_MSG_LEN];
+} xc_error;
+
+/*
+ * Return a pointer to the last error. This pointer and the
+ * data pointed to are only valid until the next call to
+ * libxc.
+ */
+const xc_error const *xc_get_last_error(void);
+
+/*
+ * Clear the last error
+ */
+void xc_clear_last_error(void);
+
+typedef void (*xc_error_handler)(const xc_error const* err);
+
+/*
+ * The default error handler which prints to stderr
+ */
+void xc_default_error_handler(const xc_error const* err);
+
+/*
+ * Convert an error code into a text description
+ */
+const char *xc_error_code_to_desc(int code);
+
+/*
+ * Registers a callback to handle errors
+ */
+xc_error_handler xc_set_error_handler(xc_error_handler handler);
+
#endif
#define PKG "xen.lowlevel.xc"
#define CLS "xc"
-static PyObject *xc_error, *zero;
+static PyObject *xc_error_obj, *zero;
typedef struct {
PyObject_HEAD;
static PyObject *dom_op(XcObject *self, PyObject *args,
int (*fn)(int, uint32_t));
+static PyObject *pyxc_error_to_exception(void)
+{
+ PyObject *pyerr;
+ const xc_error const *err = xc_get_last_error();
+ const char *desc = xc_error_code_to_desc(err->code);
+
+ if (err->message[1])
+ pyerr = Py_BuildValue("(iss)", err->code, desc, err->message);
+ else
+ pyerr = Py_BuildValue("(is)", err->code, desc);
+
+ xc_clear_last_error();
+
+ PyErr_SetObject(xc_error_obj, pyerr);
+
+ return NULL;
+}
static PyObject *pyxc_domain_dumpcore(XcObject *self, PyObject *args)
{
return NULL;
if (xc_domain_dumpcore(self->xc_handle, dom, corefile) != 0)
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
if ( (ret = xc_domain_create(self->xc_handle, ssidref,
handle, flags, &dom)) < 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
return PyInt_FromLong(dom);
out_exception:
errno = EINVAL;
- PyErr_SetFromErrno(xc_error);
+ PyErr_SetFromErrno(xc_error_obj);
return NULL;
}
return NULL;
if (xc_domain_max_vcpus(self->xc_handle, dom, max) != 0)
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
}
if ( xc_vcpu_setaffinity(self->xc_handle, dom, vcpu, cpumap) != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
return NULL;
if ( xc_domain_setcpuweight(self->xc_handle, dom, cpuweight) != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
}
if (xc_domain_sethandle(self->xc_handle, dom, handle) < 0)
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
out_exception:
- errno = EINVAL;
- PyErr_SetFromErrno(xc_error);
+ PyErr_SetFromErrno(xc_error_obj);
return NULL;
}
if (nr_doms < 0)
{
free(info);
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
}
list = PyList_New(nr_doms);
rc = xc_vcpu_getinfo(self->xc_handle, dom, vcpu, &info);
if ( rc < 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
rc = xc_vcpu_getaffinity(self->xc_handle, dom, vcpu, &cpumap);
if ( rc < 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
info_dict = Py_BuildValue("{s:i,s:i,s:i,s:L,s:i}",
"online", info.online,
ramdisk, cmdline, features, flags,
store_evtchn, &store_mfn,
console_evtchn, &console_mfn) != 0 ) {
- if (!errno)
- errno = EINVAL;
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
}
return Py_BuildValue("{s:i,s:i}",
"store_mfn", store_mfn,
return NULL;
if ( xc_hvm_build(self->xc_handle, dom, memsize, image) != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
/* Set up the HVM info table. */
va_map = xc_map_foreign_range(self->xc_handle, dom, XC_PAGE_SIZE,
PROT_READ | PROT_WRITE,
HVM_INFO_PFN);
if ( va_map == NULL )
- return PyErr_SetFromErrno(xc_error);
+ return PyErr_SetFromErrno(xc_error_obj);
va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
memset(va_hvm, 0, sizeof(*va_hvm));
strncpy(va_hvm->signature, "HVM INFO", 8);
return NULL;
if ( (port = xc_evtchn_alloc_unbound(self->xc_handle, dom, remote_dom)) < 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
return PyInt_FromLong(port);
}
ret = xc_physdev_pci_access_modify(
self->xc_handle, dom, bus, dev, func, enable);
if ( ret != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
ret = xc_readconsolering(self->xc_handle, &str, &count, clear);
if ( ret < 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
return PyString_FromStringAndSize(str, count);
}
int i;
if ( xc_physinfo(self->xc_handle, &info) != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
*q=0;
for(i=0;i<sizeof(info.hw_cap)/4;i++)
xen_version = xc_version(self->xc_handle, XENVER_version, NULL);
if ( xc_version(self->xc_handle, XENVER_extraversion, &xen_extra) != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
if ( xc_version(self->xc_handle, XENVER_compile_info, &xen_cc) != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
if ( xc_version(self->xc_handle, XENVER_changeset, &xen_chgset) != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
if ( xc_version(self->xc_handle, XENVER_capabilities, &xen_caps) != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
if ( xc_version(self->xc_handle, XENVER_platform_parameters, &p_parms) != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
sprintf(str, "virt_start=0x%lx", p_parms.virt_start);
xen_pagesize = xc_version(self->xc_handle, XENVER_pagesize, NULL);
if (xen_pagesize < 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
return Py_BuildValue("{s:i,s:i,s:s,s:s,s:i,s:s,s:s,s:s,s:s,s:s,s:s}",
"xen_major", xen_version >> 16,
return NULL;
if ( xc_sedf_domain_set(self->xc_handle, domid, period,
slice, latency, extratime,weight) != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
if (xc_sedf_domain_get(self->xc_handle, domid, &period,
&slice,&latency,&extratime,&weight))
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
return Py_BuildValue("{s:i,s:L,s:L,s:L,s:i,s:i}",
"domid", domid,
if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, NULL, 0, NULL)
< 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
op = XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION;
}
if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, &mb, 0, NULL) < 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
mbarg = mb;
return Py_BuildValue("i", mbarg);
int sched_id;
if (xc_sched_id(self->xc_handle, &sched_id) != 0)
- return PyErr_SetFromErrno(xc_error);
+ return PyErr_SetFromErrno(xc_error_obj);
return Py_BuildValue("i", sched_id);
}
sdom.cap = cap;
if ( xc_sched_credit_domain_set(self->xc_handle, domid, &sdom) != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
return NULL;
if ( xc_sched_credit_domain_get(self->xc_handle, domid, &sdom) != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
return Py_BuildValue("{s:H,s:H}",
"weight", sdom.weight,
return NULL;
if (xc_domain_setmaxmem(self->xc_handle, dom, maxmem_kb) != 0)
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
if ( xc_domain_memory_increase_reservation(self->xc_handle, dom,
nr_extents, extent_order,
address_bits, NULL) )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
ret = xc_domain_ioport_permission(
self->xc_handle, dom, first_port, nr_ports, allow_access);
if ( ret != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
ret = xc_domain_irq_permission(
xc->xc_handle, dom, pirq, allow_access);
if ( ret != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
ret = xc_domain_iomem_permission(
xc->xc_handle, dom, first_pfn, nr_pfns, allow_access);
if ( ret != 0 )
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
return NULL;
if (fn(self->xc_handle, dom) != 0)
- return PyErr_SetFromErrno(xc_error);
+ return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
PyXc_init(XcObject *self, PyObject *args, PyObject *kwds)
{
if ((self->xc_handle = xc_interface_open()) == -1) {
- PyErr_SetFromErrno(xc_error);
+ pyxc_error_to_exception();
return -1;
}
if (m == NULL)
return;
- xc_error = PyErr_NewException(PKG ".Error", PyExc_RuntimeError, NULL);
+ xc_error_obj = PyErr_NewException(PKG ".Error", PyExc_RuntimeError, NULL);
zero = PyInt_FromLong(0);
/* KAF: This ensures that we get debug output in a timely manner. */
Py_INCREF(&PyXcType);
PyModule_AddObject(m, CLS, (PyObject *)&PyXcType);
- Py_INCREF(xc_error);
- PyModule_AddObject(m, "Error", xc_error);
+ Py_INCREF(xc_error_obj);
+ PyModule_AddObject(m, "Error", xc_error_obj);
/* Expose some libxc constants to Python */
PyModule_AddIntConstant(m, "XEN_SCHEDULER_SEDF", XEN_SCHEDULER_SEDF);